package com.jinzhi.jzweb.service.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.utils.Result;
import com.jinzhi.jzapi.utils.CerSynthesisUtil;
import com.jinzhi.jzapi.utils.ITextPdfUtil;
import com.jinzhi.jzweb.domain.ApplyCheckRecordDO;
import com.jinzhi.jzweb.domain.MessageplatfromDO;
import com.jinzhi.jzweb.domain.enumConstants.IntentionEnum;
import com.jinzhi.jzweb.domain.vo.MemberApplyVo;
import com.jinzhi.jzweb.service.ApplyCheckRecordService;
import com.jinzhi.jzweb.service.MessageplatfromService;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.jzweb.utils.ValuesUtil;
import com.jinzhi.sms.support.SmsManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jinzhi.jzweb.dao.MemberApplyDao;
import com.jinzhi.jzweb.domain.MemberApplyDO;
import com.jinzhi.jzweb.service.MemberApplyService;
import com.jinzhi.common.base.CoreServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 
 * <pre>
 * 成员申请表
 * </pre>
 * <small> 2024-06-18 11:09:22 | lance</small>
 */
@Service
public class MemberApplyServiceImpl extends CoreServiceImpl<MemberApplyDao, MemberApplyDO> implements MemberApplyService {

    @Autowired
    private ApplyCheckRecordService applyCheckRecordService;
    @Autowired
    private SmsManager smsSerevice;
    @Autowired
    private DictService dictService;
    @Autowired
    private MessageplatfromService messageplatfromService;
    @Override
    public Result<Page<MemberApplyDO>> selMemberApplyList(Integer unitType, String name, int current, int size, Integer checkStatus, Integer checkResult) {
        Page<MemberApplyDO> page = new Page<>(current, size);
        List<MemberApplyDO> voList = new ArrayList<>();
        Wrapper<MemberApplyDO> wrapper = new EntityWrapper<>();

        if (StringUtils.isNotBlank(name)) {
            wrapper.like("name", "%" + name + "%");
        }
        if (unitType != null && unitType != -1) {
            wrapper.eq("unit_type", unitType);
        }
        if (checkStatus != null && checkStatus != -1) {
            wrapper.eq("check_status", checkStatus);
        }

        wrapper.eq("is_delete", 0);
        wrapper.orderBy("create_date", false);
        wrapper.orderBy("check_status");
        Page<MemberApplyDO> memberApplyDOPage = this.selectPage(page, wrapper);

        for (MemberApplyDO memberApplyDO : memberApplyDOPage.getRecords()) {
            MemberApplyDO vo = new MemberApplyDO();
            BeanUtils.copyProperties(memberApplyDO, vo);
            vo.setIssueUnit(memberApplyDO.getIssueUnit());

            // 查询最新的审核记录
            ApplyCheckRecordDO applyCheckRecordDO = applyCheckRecordService.selectOne(
                    new EntityWrapper<ApplyCheckRecordDO>()
                            .eq("apply_id", memberApplyDO.getId())
                            .orderBy("create_date", false)
                            .last("LIMIT 1")
            );

            // 判断当前审核状态是否为待审核
            boolean isPending = memberApplyDO.getCheckStatus().equals(0);

            if (applyCheckRecordDO != null) {
                // 如果当前审核状态为待审核，且有审核记录，但传入了 checkResult，则跳过
                if (isPending) {
                    if (checkResult != null && checkResult != -1) {
                        continue;
                    }
                    vo.setCheckResult(null);
                } else {
                    // 如果传递了 checkResult 参数，且不匹配，则跳过此记录
                    if (checkResult != null && checkResult != -1 && !Objects.equals(applyCheckRecordDO.getCheckResult(), checkResult)) {
                        continue;
                    }
                    vo.setCheckResult(applyCheckRecordDO.getCheckResult());
                }
            } else {
                // 如果没有审核记录，且传递了 checkResult 参数，则跳过此记录
                if (checkResult != null && checkResult != -1) {
                    continue;
                }
            }

            voList.add(vo);
        }

        System.out.println("Returning result with records: " + voList.size());

        memberApplyDOPage.setRecords(voList);
        return Result.ok(memberApplyDOPage);



    }

    @Override
    public Result<Page<MemberApplyDO>> selCertificateList(Integer unitType, String name, int current, int size, Integer status, Integer intention) {
        Page<MemberApplyDO> page = new Page<>(current, size);
        List<MemberApplyDO> voList = new ArrayList<>();
        Wrapper<MemberApplyDO> wrapper = new EntityWrapper<>();
        wrapper.eq("check_status",1);
        wrapper.eq("is_delete",0);
        if (StringUtils.isNotBlank(name)) {
            wrapper.like("name", "%"+name+"%");
        }
        if (unitType!=null&& unitType != -1) {
            wrapper.eq("unit_type", unitType);
        }
        if (status != null && status != -1) {
            wrapper.eq("status", status);
        }
        if (intention!=null&& intention != -1) {
            wrapper.eq("intention", intention);
        }
        wrapper.orderBy("status");
        wrapper.orderBy("create_date", false);
        Page<MemberApplyDO> memberApplyDOPage = this.selectPage(page, wrapper);
        for (MemberApplyDO memberApplyDO : memberApplyDOPage.getRecords()) {
            MemberApplyDO vo = new MemberApplyDO();
            ApplyCheckRecordDO applyCheckRecordDO = applyCheckRecordService.selectOne(new EntityWrapper<ApplyCheckRecordDO>().eq("apply_id", memberApplyDO.getId()).orderBy("create_date", false).last("LIMIT 1"));
            if (applyCheckRecordDO != null &&applyCheckRecordDO.getCheckResult().equals(0)){
                BeanUtils.copyProperties(memberApplyDO, vo);
                vo.setCheckResult(applyCheckRecordDO.getCheckResult());
                vo.setIssueUnit(memberApplyDO.getIssueUnit());
                voList.add(vo);
            }
        }
        memberApplyDOPage.setRecords(voList);
        return Result.ok(memberApplyDOPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> updateMemberApply(MemberApplyDO cond) {
        MemberApplyDO memberApplyDO = this.selectById(cond.getId());
        BeanUtils.copyProperties(cond,memberApplyDO);
        this.updateById(memberApplyDO);

        return Result.ok();
    }

    @Override
    public Result<?> downloadMemberApply(HttpServletResponse response) {
        List<Map<String, Object>> sheetsList = new ArrayList<>();

        sheetsList.add(createSheet("订单职业学校", getList(0)));
        sheetsList.add(createSheet("科研机构", getList(1)));
        sheetsList.add(createSheet("上下游企业", getList(2)));
        sheetsList.add(createSheet("行业机构组织", getList(3)));
        sheetsList.add(createSheet("他单位", getList(4)));
        sheetsList.add(createSheet("Sheet1", getList(5)));

        EasyPoiUtil.exportExcel(sheetsList, "申请用户表", response);
        return Result.ok();
    }

    @Override
    public MemberApplyDO getInfo(Long id) {
        MemberApplyDO memberApplyDO = this.selectById(id);
        List<ApplyCheckRecordDO> applyId = applyCheckRecordService.selectList(new EntityWrapper<ApplyCheckRecordDO>().eq("apply_id", id));
        memberApplyDO.setCheckRecordDOS(applyId);
        return memberApplyDO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getCertificateList(List<Long> ids, String unitTraSynthesis, String personalTraSynthesis, String electronic) {
        Wrapper<MemberApplyDO> wrapper=new EntityWrapper<>();
        if (!ids.isEmpty()){
            wrapper.in("id",ids);
        }
        List<MemberApplyDO> memberApplyDOS = this.selectList(wrapper);
        for (int i = 0; i < memberApplyDOS.size(); i++) {
             //单位证书图片
            String unitCerImgUrl = null;
            String unitCerImgUrlNoSale = null;
            //个人证书图片
            String personalCerImgUrl = null;
            String personalCerImgUrlNoSale = null;
            // 创建一个SimpleDateFormat对象，可以指定日期/时间格式
            Date createDate = memberApplyDOS.get(i).getCreateDate();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 使用format()方法将Date转换为字符串
            String strDate = sdf.format(createDate);
            try {
                //合成类型（0带公章，1不带公章）
//                unitCerImgUrl = CerSynthesisUtil.yzyyUnit(0,memberApplyDOS.get(i),unitTraSynthesis,electronic,strDate);
                unitCerImgUrlNoSale = CerSynthesisUtil.yzyyUnit(1,memberApplyDOS.get(i),unitTraSynthesis,electronic,strDate);
                //合成类型（0带公章，1不带公章）
//                personalCerImgUrl = CerSynthesisUtil.yzyyPersonal(0,memberApplyDOS.get(i),personalTraSynthesis,electronic,strDate);
                personalCerImgUrlNoSale = CerSynthesisUtil.yzyyPersonal(1,memberApplyDOS.get(i),personalTraSynthesis,electronic,strDate);
            } catch (Exception e) {
                e.printStackTrace();
            }

            //转换一下图片路径，将反斜杠替换掉
            String url = unitCerImgUrlNoSale.replace(ValuesUtil.localUrl, ValuesUtil.returnUrl);
            String imgUrl = url.replace("\\", "/");
            memberApplyDOS.get(i).setUnitEmployment(imgUrl);

            String url1 = personalCerImgUrlNoSale.replace(ValuesUtil.localUrl, ValuesUtil.returnUrl);
            String imgUrl1 = url1.replace("\\", "/");
            memberApplyDOS.get(i).setPersonalEmployment(imgUrl1);
            memberApplyDOS.get(i).setCertificateTime(new Date());
            memberApplyDOS.get(i).setStatus(1);

        }
        this.updateBatchById(memberApplyDOS);
        System.out.println("修改成功------------------------------------------------------------------------------------");

    }

    @Override
    public void exportUnitPdf(List<Long> ids, HttpServletResponse response) {
        Wrapper<MemberApplyDO> wrapper=new EntityWrapper<>();
        if (!ids.isEmpty()){
            wrapper.in("id",ids);
        }
        List<MemberApplyDO> memberApplyDOS = this.selectList(wrapper);
        //获得所有的单位证书链接
        List<String> imgUrls = memberApplyDOS.stream().map(MemberApplyDO::getUnitEmployment).collect(Collectors.toList());
        try {
            creatPdf("单位证书",imgUrls,1);
            File file = new File(ValuesUtil.localUrl + "/work/" + "单位证书" + ".pdf");
            String filepath = file.getPath();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(("单位证书" + ".pdf").getBytes(), "iso-8859-1"));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException | DocumentException ex) {
            ex.printStackTrace();
        }


    }

    @Override
    public void exportPersonalPdf(List<Long> ids, HttpServletResponse response) {
        Wrapper<MemberApplyDO> wrapper=new EntityWrapper<>();
        if (!ids.isEmpty()){
            wrapper.in("id",ids);
        }
        List<MemberApplyDO> memberApplyDOS = this.selectList(wrapper);
        //获得所有的个人证书链接
        List<String> imgUrls = memberApplyDOS.stream().map(MemberApplyDO::getPersonalEmployment).collect(Collectors.toList());
        try {
            creatPdf("个人证书",imgUrls,2);
            File file = new File(ValuesUtil.localUrl + "/work/" + "个人证书" + ".pdf");
            String filepath = file.getPath();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(("个人证书" + ".pdf").getBytes(), "iso-8859-1"));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException | DocumentException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getCertificate(Long id, String unitTraSynthesis, String personalTraSynthesis, String electronic) {
        MemberApplyDO memberApplyDO = this.selectById(id);

        //单位证书图片
        String unitCerImgUrl = null;
        String unitCerImgUrlNoSale = null;
        //个人证书图片
        String personalCerImgUrl = null;
        String personalCerImgUrlNoSale = null;
        // 创建一个SimpleDateFormat对象，可以指定日期/时间格式
        Date createDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 使用format()方法将Date转换为字符串
        String strDate = sdf.format(createDate);
        try {
            //合成类型（0带公章，1不带公章）
            unitCerImgUrl = CerSynthesisUtil.yzyyUnit(0,memberApplyDO,unitTraSynthesis,electronic,strDate);
            unitCerImgUrlNoSale = CerSynthesisUtil.yzyyUnit(1,memberApplyDO,unitTraSynthesis,electronic,strDate);
            //合成类型（0带公章，1不带公章）
            personalCerImgUrl = CerSynthesisUtil.yzyyPersonal(0,memberApplyDO,personalTraSynthesis,electronic,strDate);
            personalCerImgUrlNoSale = CerSynthesisUtil.yzyyPersonal(1,memberApplyDO,personalTraSynthesis,electronic,strDate);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //转换一下图片路径，将反斜杠替换掉
        String url = unitCerImgUrlNoSale.replace(ValuesUtil.localUrl, ValuesUtil.returnUrl);
        String imgUrl = url.replace("\\", "/");
        memberApplyDO.setUnitEmployment(imgUrl);

        String url1 = personalCerImgUrlNoSale.replace(ValuesUtil.localUrl, ValuesUtil.returnUrl);
        String imgUrl1 = url1.replace("\\", "/");
        memberApplyDO.setPersonalEmployment(imgUrl1);
        memberApplyDO.setCertificateTime(new Date());

        memberApplyDO.setStatus(1);
        this.updateById(memberApplyDO);
        System.out.println("修改成功------------------------------------------------------------------------------------");

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> checkMemberApply(Long id, String reason, Integer checkResult) {
        MemberApplyDO memberApplyDO = this.selectById(id);
        memberApplyDO.setCheckStatus(1);
        ApplyCheckRecordDO applyCheckRecordDO=new ApplyCheckRecordDO();
        applyCheckRecordDO.setApplyId(id);
        applyCheckRecordDO.setCheckResult(checkResult);
        if (checkResult.equals(1)){
            applyCheckRecordDO.setReason(reason);
            Map<String,String> map = new HashMap<>();
            map.put("type","send_mes");
            map.put("name","全国婴幼儿照护服务共同体秘书处");
            //拒绝后可以联系的电话
            String system_invoice = dictService.selDicBy(map);
            Wrapper<MessageplatfromDO> wrapperor = new EntityWrapper<MessageplatfromDO>();
            wrapperor.eq("name","全国婴幼儿照护服务共同体");
            List<MessageplatfromDO> list=messageplatfromService.selectList(wrapperor);
            if(list.size()==0){
                return Result.fail("短信模板不存在！");
            }
            //拒绝短信
            Map  map1org=new HashMap();
            map1org.put("name",memberApplyDO.getRecommend());
            map1org.put("phone",system_invoice);
            smsSerevice.send1(memberApplyDO.getRecommPhone(),"SMS_468535014","全国婴幼儿照护服务共同体",map1org);
        }else {
            //同意短信
            Map  map1org=new HashMap();
            map1org.put("name",memberApplyDO.getRecommend());
            smsSerevice.send1(memberApplyDO.getRecommPhone(),"SMS_468640019","全国婴幼儿照护服务共同体",map1org);
        }
//        applyCheckRecordDO.setCheckStatus(1);
        applyCheckRecordDO.setCreateDate(new Date());
        this.updateById(memberApplyDO);
        applyCheckRecordService.insert(applyCheckRecordDO);
         return Result.ok();
    }

    @Override
    public void exportPdf(Long id, HttpServletResponse response) {
        MemberApplyDO memberApplyDO = this.selectById(id);

        //获得个人的证书链接
        List<String> imgUrls =new ArrayList<>();
        imgUrls.add(memberApplyDO.getPersonalEmployment());
        imgUrls.add(memberApplyDO.getUnitEmployment());
        try {
            creatPdf(memberApplyDO.getName(),imgUrls,1);
            File file = new File(ValuesUtil.localUrl + "/work/" +memberApplyDO.getName() + ".pdf");
            String filepath = file.getPath();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String((memberApplyDO.getName() + ".pdf").getBytes(), "iso-8859-1"));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException | DocumentException ex) {
            ex.printStackTrace();
        }

    }

    private void creatPdf(String pdfName, List<String> imgUrls, int type) throws IOException, DocumentException {
        Rectangle pageSize;
        if (type==1){
            pageSize=new Rectangle(2000F, 2000F);
        }else {
            pageSize=new Rectangle(2000F, 1500F);
        }

        Document document = new Document(pageSize, 50, 50, 0, 50);
        // 设置相关的参数
        ITextPdfUtil.setParameters(document, "开发者", "测试", "测试 开发者 调试", "lance", "lance");
        // 第二步，设置要到出的路径
        try {
            FileOutputStream out = new FileOutputStream(ValuesUtil.localUrl + "/work/" + pdfName + ".pdf");
            // 第三步，将pdf文件输出到磁盘
            PdfWriter writer = PdfWriter.getInstance(document, out);
            // 第四步，打开生成的pdf文件
            document.open();
            // 第五步，往pdf文档中添加证书图片
            for (int i = 0; i < imgUrls.size(); i++) {

                Image image = Image.getInstance(imgUrls.get(i));
                image.setAlignment(Element.ALIGN_CENTER);//设置元素居中
                document.add(image);
            }
            // 第八步，关闭document
            document.close();
            //文件输出至服务器
            String pdffilepath = ValuesUtil.localUrl + "\\work\\" + pdfName + ".pdf";
            ITextPdfUtil.doAddWaterMark(pdffilepath, pdfName, 38, "255, 200, 0", "4, 550", 10);


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private Map<String, Object> createSheet(String sheetName, List<MemberApplyVo> data) {
        Map<String, Object> sheet = new HashMap<>();
        sheet.put("title", new ExportParams(sheetName, sheetName));
        sheet.put("entity", MemberApplyVo.class);
        sheet.put("data", data);
        return sheet;
    }

    private List<MemberApplyVo> getList(int i) {
        List<MemberApplyVo> voList = new ArrayList<>();
        Wrapper<MemberApplyDO> wrapper = new EntityWrapper<>();
        wrapper.eq("is_delete",0);
        wrapper.eq("unit_type",i);
        List<MemberApplyDO> memberApplyDOS = this.selectList(wrapper);
        memberApplyDOS.forEach(e->{
            MemberApplyVo vo=new MemberApplyVo();
            BeanUtils.copyProperties(e,vo);
            String province = extractProvince(e.getAddress());
            String city = extractCity(e.getAddress(), province);
            String area = extractDistrict(e.getAddress(), province,city);
            vo.setProvince(StringUtils.isNotBlank(province)?province:"");
            vo.setCity(StringUtils.isNotBlank(city)?city:"");
            vo.setArea(StringUtils.isNotBlank(area)?area:"");
//            vo.setUnitType(UnitTypeEnum.getDescpByCode(e.getUnitType().toString()));
            vo.setIntention(IntentionEnum.getDescpByCode(e.getIntention().toString()));
//            vo.setCheckStatus(e.getCheckStatus()!=0?"已审核":"待审核");
//            if (e.getCheckResult()!=null){
//                vo.setCheckResult(e.getCheckResult()!=0?"已拒绝":"已通过");
//            }
            vo.setStatus(e.getStatus()!=0?"已生成":"待生成");
            voList.add(vo);
        });
        return voList;
    }

    private static String extractProvince(String address) {
        int provinceIndex = address.indexOf("省");
        if (provinceIndex != -1) {
            return address.substring(0, provinceIndex + 1);
        }
        int autonomousRegionIndex = address.indexOf("自治区");
        if (autonomousRegionIndex != -1) {
            return address.substring(0, autonomousRegionIndex + 3);
        }
        if (address.contains("市")) {
            // 直辖市的情况，例如北京市、上海市、天津市、重庆市
            return address.substring(0, address.indexOf("市") + 1);
        }
        return "";
    }

    private static String extractCity(String address, String province) {
        int provinceLength = province.isEmpty() ? 0 : province.length();
        int cityIndex = address.indexOf("市", provinceLength);
        if (cityIndex != -1) {
            return address.substring(provinceLength, cityIndex + 1);
        }
        return "";
    }

    private static String extractDistrict(String address, String province, String city) {
        int startIndex = province.length() + city.length();
        String[] districtKeywords = {"区", "镇", "县"};
        for (String keyword : districtKeywords) {
            int districtIndex = address.indexOf(keyword, startIndex);
            if (districtIndex != -1) {
                return address.substring(startIndex, districtIndex + 1);
            }
        }
        return "";
    }
}
